package com.alogic.validator.impl;

import com.alogic.validator.Validator;
import com.anysoft.util.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.util.ArrayList;
import java.util.List;

/**
 * 组合validator
 *
 * @version 1.6.13.17 [20200923 duanyy] <br>
 * - 优化validator接口
 *
 * @version 1.6.13.25 [20201110 duanyy] <br>
 * - 修复validator的问题
 *
 * @version 1.6.13.31 [20210108 duanyy] <br>
 * - 加载sink对象列表时增加enable开关 <br>
 */
public class Combo extends Validator.Abstract{
    protected List<Validator> sinks = new ArrayList<Validator>();

    @Override
    public boolean check(String value, Properties ctx,boolean throwException) {
        boolean result = true;
        for (Validator v:sinks){
            result = v.check(value,ctx,false);
            if (!result){
                break;
            }
        }

        if (!result && throwException){
            throw new BaseException(getCode(ctx),getMessage(ctx));
        }
        return result;
    }

    @Override
    public boolean check(String value, Properties ctx, Listener listener) {
        boolean totalResult = true;
        for (Validator v:sinks){
            boolean result = v.check(value,ctx,false);
            if (!result) {
                totalResult = false;
            }
            if (listener != null){
                boolean toContinue = listener.result(result,value,v,ctx);
                if (!toContinue){
                    break;
                }
            }else {
                if (!result) {
                    break;
                }
            }
        }
        return totalResult;
    }

    @Override
    public void configure(Element e, Properties p) {
        XmlElementProperties props = new XmlElementProperties(e,p);
        configure(props);

        NodeList nodeList = XmlTools.getNodeListByPath(e, "validator");
        Factory<Validator> factory = new Factory<Validator>();
        String scope = PropertiesConstants.getString(p, "ketty.scope", "runtime");

        for (int i = 0 ;i < nodeList.getLength() ; i ++){
            Node n = nodeList.item(i);

            if (Node.ELEMENT_NODE != n.getNodeType()){
                continue;
            }

            Element elem = (Element)n;

            XmlElementProperties itemProps = new XmlElementProperties(elem,props);
            String itemScope = PropertiesConstants.getString(itemProps,"scope","",true);
            if (StringUtils.isNotEmpty(itemScope) && !itemScope.equals(scope)){
                continue;
            }

            boolean enable = PropertiesConstants.getBoolean(itemProps,"enable",true,true);
            if (!enable){
                continue;
            }

            try {
                Validator validator = factory.newInstance(elem, props, "module");
                if (validator != null){
                    sinks.add(validator);
                }
            }catch (Exception ex){
                LOG.error("Can not create validator from element:" + XmlTools.node2String(elem));
                LOG.error(ExceptionUtils.getStackTrace(ex));
            }
        }
    }
}
